/**
 * This file is part of 1genia trampoline
 * Copyright (C) 2007 1genia (contact@1genia.com)
 *
 * This library is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; version 3 of the License. 
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details. 
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; see the file COPYING.TXT.  If not,
 * write to the Free Software Foundation, Inc., 51 Franklin Street,
 * Fifth Floor, Boston, MA 02110-1301, USA. 
 **/
package com.genia.toolbox.uml_generator.transformer;


import org.springframework.util.StringUtils;
import org.w3c.dom.Element;

import com.genia.toolbox.uml_generator.Constants;
import com.genia.toolbox.uml_generator.bean.ModelGeneratorContext;
import com.genia.toolbox.uml_generator.manager.NameManager;
import com.genia.toolbox.uml_generator.model.AbstractClassModel;
import com.genia.toolbox.uml_generator.model.AttributeModel;
import com.genia.toolbox.uml_generator.model.StereotypeModel;
import com.genia.toolbox.uml_generator.model.impl.AttributeModelImpl;
import com.genia.toolbox.uml_generator.model.impl.ClassModel;
import com.genia.toolbox.uml_generator.model.impl.StereotypeModelImpl;

/**
 * this class handle the input of nodes from xmi to model.
 */
public class ClassInputHandler
    extends InterfaceInputHandler
{

  /**
   * the {@link NameManager} to use.
   */
  private NameManager nameManager;



  /**
   * the actual method that parse the current {@link Element}.
   * @param context
   *          the generation context
   * @param firstPass
   *          whether it is the first or second pass
   * @param element
   *          the element to parse
   * @param parent
   *          the generated parent model
   */
  @Override
  public void processContent(final ModelGeneratorContext context, final boolean firstPass, final Element element, final Object parent)
  {
    super.processContent(context, firstPass, element, parent);

    if (firstPass) {
      AbstractClassModel model = (AbstractClassModel) context.getObject(element.getAttribute("xmi.id"));

      AbstractClassModel classModel = new ClassModel();
      classModel.setUmlId(model.getUmlId() + Constants.IMPLEMENTATION_SUFFIX);
      classModel.setPackageName(model.getPackageName());
      classModel.setName(model.getName());
      classModel.setComment("implementation of {@link " + model.getQualifiedName() + "}.");
      classModel.addImplementsModel(model);
      classModel.getStereotypes().putAll(model.getStereotypes());
      classModel.setAbstractClass(Boolean.valueOf(element.getAttribute("isAbstract")));

      model.setImplementationModel(getModelDecorator().getImplementationObject(classModel));
      context.addClassModel(model.getImplementationModel());

    }
    else {
      AbstractClassModel model = (AbstractClassModel) context.getObject(element.getAttribute("xmi.id"));
      for (Element attributeElement : getElementsByPath(context, element, "UML:Classifier.feature", "UML:Attribute")) {
        AttributeModel attribute = parseAttributeModel(context, attributeElement);
        if (!StringUtils.hasText(attribute.getComment())) {
          context.getErrors().add("Attribute " + attribute.getName() + " of class " + model.getQualifiedName() + " must have a comment.");
        }
        model.addAttribute(attribute);
        if (attribute.hasStereotype(Constants.ESCAPE_STEREOTYPE)) {
          AttributeModel escapedAttribute = new AttributeModelImpl();
          escapedAttribute.setComment("escaped value of " + attribute.getName());
          escapedAttribute.setName("escaped" + getNameManager().getUpperCaseFirstLetterName(attribute));
          escapedAttribute.setType(attribute.getType());
          escapedAttribute.setUmlId(attribute.getUmlId() + "-Escaped");
          StereotypeModel stereotype = new StereotypeModelImpl();
          stereotype.setName(Constants.INDEXED_STEREOTYPE);
          escapedAttribute.addStereotype(stereotype);
          model.addAttribute(escapedAttribute);
        }
      }
      handleGeneralization(context, element, model);
    }

  }



  /**
   * getter for the nameManager property.
   * 
   * @return the nameManager
   */
  public NameManager getNameManager()
  {
    return nameManager;
  }



  /**
   * setter for the nameManager property.
   * 
   * @param nameManager
   *          the nameManager to set
   */
  public void setNameManager(NameManager nameManager)
  {
    this.nameManager = nameManager;
  }

}
